import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Between } from 'typeorm';
import { Request } from 'express';
import { Log } from './entities/log.entity';
import { CreateLogDto, LogLevel } from './dto/create-log.dto';
import { SearchLogDto } from './dto/search-log.dto';
import { JwtService } from '@nestjs/jwt';
import { UAParser } from 'ua-parser-js';

@Injectable()
export class LogService {
  constructor(
    @InjectRepository(Log)
    private logRepository: Repository<Log>,
    private readonly jwtService: JwtService,
  ) { }

  /**
   * 记录请求日志
   */
  async logRequest(req: Request, responseData?: any, responseTime?: number, error?: any) {
    try {
      if (!responseData) return;
      const res = JSON.parse(JSON.stringify(responseData));
      console.log(res, "小麻花")
      const userAgent = req.headers['user-agent'];
      const parser = new UAParser(userAgent);
      const agent = Object.values(parser.getOS()).join(' ');
      const browser = parser.getBrowser().name;

      const logData: CreateLogDto = {
        method: req.method,
        url: req.url,
        ip: req.ip || req.connection.remoteAddress,
        userAgent: agent || undefined,
        browser: browser || undefined,
        requestBody: req.body ? JSON.stringify(req.body) : undefined,
        queryParams: Object.keys(req.query).length > 0 ? JSON.stringify(req.query) : undefined,
        responseBody: responseData ? JSON.stringify(responseData) : undefined,
        responseTime,
        level: error ? LogLevel.ERROR : LogLevel.INFO,
        errorMessage: error ? error.message : undefined,
        module: this.extractModule(req.originalUrl),
        action: res ? res.msg : '',
      };

      // 如果有用户信息，添加到日志中
      // 优先从 req['user'] 获取
      if (req['user']) {
        logData.userId = req['user'].id;
        logData.username = req['user'].username;
      } else {
        // 如果没有，尝试解析 token
        const authHeader = req.headers['authorization'];
        if (authHeader && authHeader.startsWith('Bearer ')) {
          const token = authHeader.split("Bearer ")[1];
          try {
            const payload: any = this.jwtService.verify(token);
            console.log(payload, 'payload')
            logData.userId = payload.userId;
            logData.username = payload.username;
          } catch (e) {
            // token 过期或无效，忽略，不影响日志主流程
          }
        }
      }
      await this.create(logData);
    } catch (err) {
      console.error('记录日志失败:', err);
    }
  }

  /**
   * 创建日志
   */
  async create(createLogDto: CreateLogDto): Promise<Log> {
    const log = this.logRepository.create(createLogDto);
    return await this.logRepository.save(log);
  }

  /**
   * 查询日志列表
   */
  async findAll(searchLogDto: SearchLogDto) {
    const { currentPage = 1, pageSize = 10, ...searchParams } = searchLogDto;
    const skip = (currentPage - 1) * pageSize;

    const queryBuilder = this.logRepository.createQueryBuilder('log');

    // 添加搜索条件
    if (searchParams.username) {
      queryBuilder.andWhere('log.username LIKE :username', { username: `%${searchParams.username}%` });
    }

    if (searchParams.method) {
      queryBuilder.andWhere('log.method = :method', { method: searchParams.method });
    }

    if (searchParams.url) {
      queryBuilder.andWhere('log.url LIKE :url', { url: `%${searchParams.url}%` });
    }

    if (searchParams.ip) {
      queryBuilder.andWhere('log.ip LIKE :ip', { ip: `%${searchParams.ip}%` });
    }

    if (searchParams.level) {
      queryBuilder.andWhere('log.level = :level', { level: searchParams.level });
    }

    if (searchParams.module) {
      queryBuilder.andWhere('log.module LIKE :module', { module: `%${searchParams.module}%` });
    }

    if (searchParams.action) {
      queryBuilder.andWhere('log.action LIKE :action', { action: `%${searchParams.action}%` });
    }

    if (searchParams.startDate && searchParams.endDate) {
      queryBuilder.andWhere('log.createdAt BETWEEN :startDate AND :endDate', {
        startDate: searchParams.startDate,
        endDate: searchParams.endDate,
      });
    }
    // 按创建时间倒序排列
    queryBuilder.orderBy('log.createdAt', 'DESC');

    const [logs, total] = await queryBuilder
      .skip(skip)
      .take(pageSize)
      .getManyAndCount();

    return {
      code: 200,
      msg: '获取日志列表成功',
      data: {
        list: logs,
        total,
      },
    };
  }

  /**
   * 根据ID查询日志
   */
  async findOne(id: number): Promise<Log | null> {
    return await this.logRepository.findOne({ where: { id } });
  }

  /**
   * 删除日志
   */
  async remove(id: number): Promise<void> {
    await this.logRepository.delete(id);
  }

  /**
   * 批量删除日志
   */
  async removeMany(ids: number[]): Promise<void> {
    await this.logRepository.delete(ids);
  }

  /**
   * 清理过期日志
   */
  async cleanOldLogs(days: number = 30): Promise<number> {
    const date = new Date();
    date.setDate(date.getDate() - days);

    const result = await this.logRepository
      .createQueryBuilder()
      .delete()
      .where('createdAt < :date', { date })
      .execute();

    return result.affected || 0;
  }

  /**
   * 获取日志统计信息
   */
  async getStatistics() {
    const totalLogs = await this.logRepository.count();
    const errorLogs = await this.logRepository.count({ where: { level: LogLevel.ERROR } });
    const todayLogs = await this.logRepository.count({
      where: {
        createdAt: Between(
          new Date(new Date().setHours(0, 0, 0, 0)),
          new Date(new Date().setHours(23, 59, 59, 999))
        ),
      },
    });

    return {
      totalLogs,
      errorLogs,
      todayLogs,
      errorRate: totalLogs > 0 ? ((errorLogs / totalLogs) * 100).toFixed(2) : '0',
    };
  }

  /**
   * 提取模块名称
   */
  private extractModule(url: string): string {
    const parts = url.split('/').filter(Boolean);
    return parts.length > 1 ? parts[1] : 'unknown';
  }

  /**
   * 提取操作类型
   */
  private extractAction(method: string, url: string): string {
    const parts = url.split('/').filter(Boolean);
    if (parts.length === 0) return 'unknown';

    const lastPart = parts[parts.length - 1];

    // 根据HTTP方法和URL模式判断操作类型
    switch (method) {
      case 'GET':
        return lastPart === 'list' ? '查询列表' : '查询详情';
      case 'POST':
        return '创建';
      case 'PUT':
      case 'PATCH':
        return '更新';
      case 'DELETE':
        return '删除';
      default:
        return '其他';
    }
  }

  /**
   * 记录错误日志
   */
  async logError(error: Error, context?: string, req?: Request) {
    const logData: CreateLogDto = {
      method: req?.method || 'UNKNOWN',
      url: req?.originalUrl || 'UNKNOWN',
      ip: req?.ip || req?.connection.remoteAddress,
      userAgent: req?.get('User-Agent'),
      level: LogLevel.ERROR,
      errorMessage: error.message,
      module: context || 'system',
      action: 'error',
    };

    if (req?.['user']) {
      logData.userId = req['user'].id;
      logData.username = req['user'].username;
    }

    await this.create(logData);
  }

  /**
   * 记录信息日志
   */
  async logInfo(message: string, context?: string, req?: Request) {
    const logData: CreateLogDto = {
      method: req?.method || 'SYSTEM',
      url: req?.originalUrl || 'SYSTEM',
      ip: req?.ip || req?.connection.remoteAddress,
      userAgent: req?.get('User-Agent'),
      level: LogLevel.INFO,
      errorMessage: message,
      module: context || 'system',
      action: 'info',
    };

    if (req?.['user']) {
      logData.userId = req['user'].id;
      logData.username = req['user'].username;
    }

    await this.create(logData);
  }
}
